/**
 * 中文提取工具函数
 * 用于从代码中提取中文文本，支持Vue文件和JS文件
 * 可识别模板中的中文、脚本中的中文，并区分比较语句中的中文
 *
 * 主要功能：
 * 1. 提取Vue文件中template和script部分的中文
 * 2. 提取JS文件中的中文，包括对象属性中的中文
 * 3. 识别比较语句中的中文（如 === '状态'）
 * 4. 支持中文文本的分割和去重
 * 5. 支持将中文替换为国际化的key
 */

// 国际化配置项
const i18nConfig = {
  // 配置项：指定哪些符号可以用来拆分中文句子
  // 例如：设置为 ['，', '。'] 可以将一句中文按逗号和句号拆分
  splitSymbols: [],
  // 是否排除比较语句中的中文（如 === '状态'）
  excludeComparisonChinese: true,
  // 国际化前缀，用于生成国际化key
  keyPrefix: 'page.',
  // 提取中文时是否忽略末尾冒号
  skipColon: true
};

/**
 * 通用的中文提取函数
 * @param {string} text - 要处理的文本内容
 * @param {RegExp} regex - 用于匹配中文的正则表达式
 * @param {Function} processMatch - 处理匹配结果的函数
 * @returns {Array} - 提取的中文文本匹配结果数组，包含位置信息
 */
function extractChinese (text, regex, processMatch) {
  const result = [];
  let match;
  const { splitSymbols } = i18nConfig;

  // 重置正则表达式的lastIndex
  regex.lastIndex = 0;

  // 使用exec方法逐个匹配，保留位置信息
  while ((match = regex.exec(text)) !== null) {
    let processed = processMatch(match);
    if (processed) {
      if (isInComment(match, text)) {
        continue;
      }
      // 如果配置了分隔符且处理后的文本包含分隔符，需要分割并更新索引
      if (typeof processed === 'string' && splitSymbols.length > 0 && splitSymbols.some(symbol => processed.includes(symbol))) {
        // 使用所有配置的分隔符分割文本
        let segments = [processed];
        for (const symbol of splitSymbols) {
          const newSegments = [];
          for (const seg of segments) {
            newSegments.push(...seg.split(symbol));
          }
          segments = newSegments;
        }

        let currentIndex = match.index;

        for (let segment of segments) {
          if (segment.trim()) { // 忽略空段
            if (i18nConfig.skipColon && (segment.endsWith('：') || segment.endsWith(':'))) {
              segment = segment.slice(0, -1);
            }
            result.push({
              text: segment.trim(),
              index: currentIndex,
              length: segment.length,
              match: match,
              original: match[0]
            });
            // 更新下一段的起始索引
            currentIndex += segment.length + 1; // +1 是分隔符的长度
          } else {
            currentIndex += 1; // 空段只有分隔符长度
          }
        }
      } else {
        if (i18nConfig.skipColon && (processed.endsWith('：') || processed.endsWith(':'))) {
          processed = processed.slice(0, -1);
        }
        result.push({
          text: processed,
          index: match.index,
          length: processed.length,
          match: match,
          original: match[0]
        });
      }
    }
  }

  return result;
}

// 预编译常用的正则表达式，提高性能
const CHINESE_REGEX = /[\[{【（(]*([\u4e00-\u9fa5])+(\$\{.+\}\s?)*([$a-zA-Z0-9\u4e00-\u9fff\u3000-\u303f\uff00-\uffef:,!?.、。〃“”\[\]()）【】])*/g; // 匹配中文句子
const VAR_REGEX = /\$\{[^}]+\}/g; // 匹配模板变量 {{var}} 或 ${var}
const HTML_TAGS_REGEX = /<[^>]*>|\r|\n/g; // 匹配HTML标签和特殊字符

/**
 * 处理匹配到的中文文本
 * @param {RegExpMatchArray} match - 正则表达式匹配结果
 * @returns {string|null} - 处理后的中文文本，如果不符合条件则返回null
 */
function processChinese (match) {
  // 提取匹配到的中文句子，去除前面的非中文字符
  let chineseText = match[0].replace(/^[^\u4e00-\u9fa5\[{【（(]+/g, '');
  if (chineseText.match(/[\[{【（(]/g)) {
    chineseText = chineseText.replace(/[^\u4e00-\u9fa5\]})）】]+$/, '')
  } else {
    chineseText = chineseText.replace(/[^\u4e00-\u9fa5]+$/, '')
  }
  // 去除HTML标签、换行符、引号等符号
  chineseText = chineseText.replace(HTML_TAGS_REGEX, '');

  chineseText = chineseText.replace(/("|'|`)/g, '\$1');

  // 排除包含{{变量}}格式的文本
  if (chineseText.match(/\{\{.*?\}\}/)) {
    return null;
  }

  return chineseText;
}

/**
 * 从Vue文件中提取非注释中文
 * @param {string} code - Vue文件内容
 * @returns {Object} - 包含template和script部分提取的中文
 * @returns {Array} - template: 模板部分的中文，包含位置信息
 * @returns {Object} - script: 脚本部分的中文
 * @returns {Array} - script.all: 脚本中所有中文，包含位置信息
 * @returns {Array} - script.forTranslation: 脚本中需要翻译的中文，包含位置信息
 * @returns {Array} - script.inComparison: 脚本中比较语句中的中文，包含位置信息
 * @returns {Array} - all: 所有中文（模板和脚本），包含位置信息
 */
function findNonCommentChinese (code) {
  // 将代码分割为template和script部分
  const templateMatch = code.match(/<template>[\s\S]*<\/template>/g) || [];
  const scriptMatch = code.match(/<script>[\s\S]*<\/script>/g) || [];

  const templatePart = templateMatch.length > 0 ? templateMatch[0] : '';
  const scriptPart = scriptMatch.length > 0 ? scriptMatch[0] : '';

  // 提取模板中的中文
  const allTemplateChinese = extractChinese(templatePart, CHINESE_REGEX, processChinese);
  const templateChineseForTranslation = [];
  const templateChineseInComparison = [];

  // 检查每个模板中的中文是否在比较语句中
  for (const matchInfo of allTemplateChinese) {
    // 获取中文文本周围的上下文（前后20个字符）
    const surroundingText = templatePart.substring(
      Math.max(0, matchInfo.index - 20),
      Math.min(templatePart.length, matchInfo.index + matchInfo.length + 20)
    );

    // 使用isInComparisonStatement函数检查是否在比较语句中
    const isInComparison = isInComparisonStatement(matchInfo.text, surroundingText);

    // 添加到相应的数组
    if (isInComparison) {
      templateChineseInComparison.push(matchInfo);
    } else {
      templateChineseForTranslation.push(matchInfo);
    }
  }

  // 使用findJsFileChinese处理script部分，识别比较语句中的中文
  const scriptChineseResult = findJsFileChinese(scriptPart);
  const allScriptChinese = scriptChineseResult.all;
  const scriptChineseForTranslation = scriptChineseResult.forTranslation;
  const scriptChineseInComparison = scriptChineseResult.inComparison;

  return {
    template: {
      all: allTemplateChinese,
      forTranslation: templateChineseForTranslation,
      inComparison: templateChineseInComparison
    },
    script: {
      all: allScriptChinese,
      forTranslation: scriptChineseForTranslation,
      inComparison: scriptChineseInComparison
    },
    all: [...allTemplateChinese, ...allScriptChinese],
    forTranslation: [...templateChineseForTranslation, ...scriptChineseForTranslation],
    inComparison: [...templateChineseInComparison, ...scriptChineseInComparison]
  };
}

/**
 * 从JS文件中提取中文
 * @param {string} jsCode - JS文件内容
 * @returns {Object} - 包含所有中文、需要翻译的中文和比较语句中的中文
 * @returns {Array} - all: 所有中文，包含位置信息
 * @returns {Array} - forTranslation: 需要翻译的中文，包含位置信息
 * @returns {Array} - inComparison: 比较语句中的中文，包含位置信息
 */
function findJsFileChinese (jsCode) {

  // 提取所有中文
  const allJsChinese = extractChinese(jsCode, CHINESE_REGEX, processChinese);
  const jsChineseForTranslation = [];
  const jsChineseInComparison = [];

  // 检查每个中文是否在比较语句中
  for (const matchInfo of allJsChinese) {
    // 获取中文文本周围的上下文（前后20个字符）
    const surroundingText = jsCode.substring(
      Math.max(0, matchInfo.index - 20),
      Math.min(jsCode.length, matchInfo.index + matchInfo.length + 20)
    );

    // 使用isInComparisonStatement函数检查是否在比较语句中
    const isInComparison = isInComparisonStatement(matchInfo.text, surroundingText);

    // 添加到相应的数组
    if (isInComparison) {
      jsChineseInComparison.push(matchInfo);
    } else {
      jsChineseForTranslation.push(matchInfo);
    }
  }

  return {
    all: allJsChinese,
    forTranslation: jsChineseForTranslation,
    inComparison: jsChineseInComparison
  };
}

/**
 * 将中文文本转换为国际化key
 * @param {string} [filePath=''] - 文件路径
 * @returns {string} - 生成的国际化key
 */
function generateI18nKey (filePath, index) {

  const key = `${new Date().getTime()}`.slice(-8) + `_${index}`;
  const pathArr = filePath.split(new RegExp(/(\\|\/)/));

  // 构建完整的key路径
  let keyPath = '';
  if (filePath) {
    keyPath = `${pathArr[pathArr.length - 3]}.${pathArr[pathArr.length - 1].split('.')[0]}.${key}`;
  } else {
    keyPath = `${i18nConfig.keyPrefix}${key}`;
  }

  return keyPath;
}

/**
 * 替换代码中的中文为国际化key
 * @param {string} code - 原始代码
 * @param {Object} chineseMap - 中文到国际化key的映射
 * @param {string} fileType - 文件类型，'vue' 或 'js'
 * @returns {string} - 替换后的代码
 */
function replaceChineseWithI18n (code, chineseMap, fileType = 'js', searchResult = null) {
  let result = code;

  // 根据文件类型选择不同的替换策略
  if (fileType === 'vue') {
    // 使用findNonCommentChinese函数提取Vue文件中的中文
    const chineseResult = searchResult || findNonCommentChinese(code);
    const templateMatch = result.match(/<template>[\s\S]*<\/template>/g) || [];
    const scriptMatch = result.match(/<script>[\s\S]*<\/script>/g) || [];

    // 处理template部分
    if (templateMatch.length > 0 && chineseResult.template.all.length > 0) {
      let templatePart = templateMatch[0];

      // 从后向前替换，避免位置偏移问题
      const templateChineseMatches = [...chineseResult.template.all].sort((a, b) => b.index - a.index);

      for (const matchInfo of templateChineseMatches) {
        // 获取中文文本
        const chinese = matchInfo.text;
        const i18nKey = chineseMap[chinese];

        if (!i18nKey) continue;

        if (isInComment(matchInfo, chinese)) {
          continue;
        }

        // 如果配置为排除比较语句中的中文，则检查是否在比较语句中
        const isInComparison = chineseResult.template.inComparison.some(item =>
          item.index === matchInfo.index && item.text === matchInfo.text
        );

        if (i18nConfig.excludeComparisonChinese && isInComparison) {
          continue;
        }

        // 使用当前中文再做一次匹配，获取最新位置
        const currentText = matchInfo.text;

        const currentTextAround = code.substring(Math.max(0, matchInfo.index - 20), matchInfo.index + currentText.length);

        // 从后向前查找，确保匹配到正确的位置
        // 创建一个正则表达式，使用 g 标志来匹配所有出现的中文文本
        const regex = new RegExp(`${escapeRegExp(currentTextAround)}$`, 'g');

        let match;
        let lastMatch = null;
        let currentIndex = -1;

        const currentTextIndex = currentTextAround.indexOf(currentText);

        // 查找所有匹配项
        while ((match = regex.exec(result)) !== null) {
          lastMatch = match;
          // 如果找到的位置接近原始索引，就使用这个位置
          if (Math.abs(currentTextIndex + match.index - matchInfo.index) < 10) {
            currentIndex = match.index + currentTextIndex;
            break;
          }
        }

        // 如果没有找到接近原始索引的匹配，但找到了匹配项，使用最后一个匹配项
        if (currentIndex === -1 && lastMatch !== null) {
          currentIndex = lastMatch.index;
        }

        // 如果找不到匹配，使用原始索引
        const startPos = currentIndex !== -1 ? currentIndex : matchInfo.index;
        const endPos = startPos + matchInfo.length;

        // 获取更多上下文，用于确定替换方式
        let beforeContext = templatePart.substring(Math.max(0, startPos - 30), startPos);
        let afterContext = templatePart.substring(endPos, Math.min(templatePart.length, endPos + 30));

        let replacement;

        if (isInComparison || beforeContext.match(/{\s?[^}{]+'$/)) {
          replacement = `$t('${i18nKey}')`;
          templatePart = templatePart.substring(0, startPos - 1) +
            replacement +
            templatePart.substring(endPos + 1);
          continue;
        } else if (beforeContext.match(/\[\s?[^\]\[]+'$/)) {
          replacement = `$t('${i18nKey}')`;
          templatePart = templatePart.substring(0, startPos - 1) +
            replacement +
            templatePart.substring(endPos + 1);
          continue;
        } else if (beforeContext.match(/\??[^?:]+:\s?'$/) || beforeContext.match(/[^?]+\?\s?'$/)) {
          if (afterContext.match(/^(['"])/)) {
            replacement = `$t('${i18nKey}')`;
            templatePart = templatePart.substring(0, startPos - 1) +
              replacement +
              templatePart.substring(endPos + 1);
          } else {
            replacement = `\`$\{$t('${i18nKey}')}`;
            const end = afterContext.match(/^([^'"]+?)['"]/)[1];
            templatePart = templatePart.substring(0, startPos - 1) +
              replacement + end + '`' +
              templatePart.substring(endPos + 1 + end.length);
          }
          continue;
        } else if (beforeContext.match(/\s([a-zA-Z0-9-]+)=(['"\s]+)([\u4e00-\u9fa5，。]*)$/)) {
          // 在HTML属性值中，使用:属性语法
          const attrMatch = beforeContext.match(/\s([a-zA-Z0-9-]+)=(['"\s]+)([\u4e00-\u9fa5，。]*)$/);
          if (attrMatch) {
            const attrName = attrMatch[1];
            let modifiedBeforeContext = beforeContext.replace(new RegExp(`${attrName}=['"](.*)`), attrMatch[3] ? `:${attrName}="'$1' + ` : `:${attrName}="$1`);
            let modifiedAfterContext = afterContext;
            if (afterContext.match(/^(['"]+)/)) {
              modifiedAfterContext = afterContext.replace(new RegExp(`^(['"]+)`), '"');
            } else if (afterContext.match(/^([^'"]+)(['"]+)/)) {
              modifiedAfterContext = afterContext.replace(new RegExp(`^([^'"]+)(['"]+)`), ` + '$1'"`);
            }
            const replacement = `${modifiedBeforeContext}$t('${i18nKey}')${modifiedAfterContext}`;

            // 使用基于索引的替换方法
            const contextStartPos = Math.max(0, startPos - beforeContext.length);
            const contextEndPos = Math.min(templatePart.length, endPos + afterContext.length);
            templatePart = templatePart.substring(0, contextStartPos) +
              replacement +
              templatePart.substring(contextEndPos);
            continue;
          }
        } else if (beforeContext.match(/\s:([a-zA-Z0-9-]+)=(['"]+)$/)) {
          let modifiedBeforeContext = beforeContext.replace(/(['"]+)$/, '"');
          let modifiedAfterContext = afterContext;
          if (afterContext.match(/^(['"]+)/)) {
            modifiedAfterContext = afterContext.replace(new RegExp(`^(['"]+)`), '"');
          } else if (afterContext.match(/^([^'"]+)(['"]+)/)) {
            modifiedAfterContext = afterContext.replace(new RegExp(`^([^'"]+)(['"]+)`), ` + '$1'"`);

            if (modifiedAfterContext.match(/('")/)) {
              modifiedAfterContext = modifiedAfterContext.replace(new RegExp(`('")`), '\'');
            }
          }
          const replacement = `${modifiedBeforeContext}$t('${i18nKey}')${modifiedAfterContext}`;

          // 使用基于索引的替换方法
          const contextStartPos = Math.max(0, startPos - beforeContext.length);
          const contextEndPos = Math.min(templatePart.length, endPos + afterContext.length);
          templatePart = templatePart.substring(0, contextStartPos) +
            replacement +
            templatePart.substring(contextEndPos);
          continue;
        } else if (beforeContext.match(/\s:([a-zA-Z0-9-]+)="(.*\+\s')$/)) {
          let modifiedBeforeContext = beforeContext.slice(0, -1);
          let modifiedAfterContext = afterContext.replace(new RegExp(`^([^'"]*)(['"])`), `$1`);
          const replacement = `${modifiedBeforeContext}$t('${i18nKey}')${modifiedAfterContext}`;

          // 使用基于索引的替换方法
          const contextStartPos = Math.max(0, startPos - beforeContext.length);
          const contextEndPos = Math.min(templatePart.length, endPos + afterContext.length);
          templatePart = templatePart.substring(0, contextStartPos) +
            replacement +
            templatePart.substring(contextEndPos);
          continue;
        } else if (beforeContext.match(/\s:([a-zA-Z0-9-]+)="`/)) {
          replacement = `\${$t('${i18nKey}')\}`;
        } else if (beforeContext.match(/\s([a-zA-Z0-9-]+)=(['"])/) && afterContext.match(/^([：:]?)(['"])/)) {
          // 在属性值中，但不是完整匹配，可能是部分文本
          replacement = `{{ $t('${i18nKey}') }}`;
        } else if (beforeContext.match(/<[^>]*>\s*$/) || afterContext.match(/^([：:]?)\s*<\/[^>]*>/)) {
          // 在标签内的文本内容
          replacement = `{{ $t('${i18nKey}') }}`;
        } else if (beforeContext.match(/{{[^{]+'$/) || afterContext.match(/^'[^}]+}}/)) {
          // 在标签内的文本内容
          replacement = `$t('${i18nKey}')`;
          templatePart = templatePart.substring(0, startPos - 1) +
            replacement +
            templatePart.substring(endPos + 1);
          continue;
        } else {
          // 默认情况，使用插值语法
          replacement = `{{ $t('${i18nKey}') }}`;
        }

        // 执行替换
        templatePart = templatePart.substring(0, startPos) +
          replacement +
          templatePart.substring(endPos);
      }

      // 更新template部分
      result = result.replace(templateMatch[0], templatePart);
    }

    // 处理script部分
    if (scriptMatch.length > 0 && chineseResult.script.all.length > 0) {
      let scriptPart = scriptMatch[0];
      scriptPart = replaceChineseWithI18nInJsCode(scriptPart, chineseResult.script.all, chineseResult.script.inComparison, chineseMap, false);

      // 更新script部分
      result = result.replace(scriptMatch[0], scriptPart);
    }
  } else {
    // 处理JS文件，使用findJsFileChinese函数提取中文
    const jsChineseResult = searchResult || findJsFileChinese(code);
    result = replaceChineseWithI18nInJsCode(result, jsChineseResult.all, jsChineseResult.inComparison, chineseMap, true);
  }

  return result;
}

/**
 * 替换js代码中的中文为国际化key
 * @param {string} jsCode - 原始代码
 * @param {Array} allChineseArr - 所有中文数组
 * @param {Array} inComparison - 比较语句中的中文数组
 * @param {Object} chineseMap - 中文到国际化key的映射
 * @param {boolean} needImport - 是否需要导入i18n模块
 * @returns {string} - 替换后的代码
 */
function replaceChineseWithI18nInJsCode (jsCode, allChineseArr, inComparison, chineseMap, needImport) {
  let result = jsCode;

  // 检查是否需要添加_self定义
  let needAddSelfDefinition = false;

  // 从后向前替换，避免位置偏移问题
  const scriptChineseMatches = [...allChineseArr].sort((a, b) => b.index - a.index);

  for (const matchInfo of scriptChineseMatches) {
    // 获取中文文本
    const chinese = matchInfo.text;

    let varText = '';
    let varArr = [];
    if (VAR_REGEX.test(chinese)) {
      varText = chinese;
      const params = chinese.match(VAR_REGEX);
      params.forEach((param, index) => {
        // 尝试从参数中提取变量名
        const paramContent = param.slice(2, -1); // 去掉 ${ 和 }
        varArr.push(paramContent);
        varText = varText.replace(param, `{${index}}`);
      });
    }

    let i18nKey = chineseMap[varText || chinese];

    if (isInComment(matchInfo, chinese)) {
      continue;
    }
    if (!i18nKey) continue;

    if (varText && varArr.length) {
      i18nKey = `'${i18nKey}', [${varArr.toString()}]`
    } else {
      i18nKey = `'${i18nKey}'`
    }

    // 如果配置为排除比较语句中的中文，则检查是否在比较语句中
    const isInComparison = inComparison.some(item =>
      item.index === matchInfo.index && item.text === matchInfo.text
    );

    if (i18nConfig.excludeComparisonChinese && isInComparison) {
      continue;
    }

    // 使用当前中文上下文再做一次匹配，获取最新位置
    const currentText = matchInfo.text;

    const currentTextAround = jsCode.substring(Math.max(0, matchInfo.index - 20), matchInfo.index + currentText.length);

    // 从后向前查找，确保匹配到正确的位置
    // 创建一个正则表达式，使用 g 标志来匹配所有出现的中文文本
    const regex = new RegExp(escapeRegExp(currentTextAround), 'g');

    let match;
    let lastMatch = null;
    let currentIndex = -1;
    const currentTextIndex = currentTextAround.indexOf(currentText);

    // 查找所有匹配项
    while ((match = regex.exec(result)) !== null) {
      lastMatch = match;
      // 如果找到的位置接近原始索引，就使用这个位置
      if (Math.abs(currentTextIndex + match.index - matchInfo.index) < 10) {
        currentIndex = match.index + currentTextIndex;
        break;
      }
    }

    // 如果找不到匹配，使用原始索引
    let startPos = currentIndex !== -1 ? currentIndex : matchInfo.index;
    let endPos = startPos + matchInfo.length;

    needAddSelfDefinition = false;
    // 判断当前中文是否在闭包定义的局部方法中
    const contextBefore = result.substring(Math.max(0, startPos - 200), startPos);
    const isInFunction = /[^\(]function[\s\w]*\([^)]*\)\s*{[\s\S]*$/.test(contextBefore) ||
      /[=:]\s*\([^)]*\)\s*=>[\s\S]*$/.test(contextBefore);

    if (!needImport && isInFunction) {
      needAddSelfDefinition = true;

      // 找到函数定义的位置
      let functionStartPos = -1;
      let functionMatch;
      let partBraceCount = 0;

      // 查找函数定义的正则表达式
      const functionRegex = /(function[\s\w]*\([^)]*\)\s*{)|(=>\s*{)|(\([^)]*\)\s*=>)/g;

      // 在上下文中查找最后一个函数定义
      while ((functionMatch = functionRegex.exec(contextBefore)) !== null) {
        functionStartPos = functionMatch.index;
      }

      for (let j = functionStartPos + 1; j < contextBefore.length; j++) {
        if (contextBefore[j] === '{') {
          partBraceCount++;
        } else if (contextBefore[j] === '}') {
          if (partBraceCount === 1) {
            // 函数已经结束，说明中文不在函数内
            needAddSelfDefinition = false;
            break;
          }
          partBraceCount--;
        }
      }

      // 如果需要添加_self定义，在局部方法之前一行添加
      if (needAddSelfDefinition && !contextBefore.includes('const _self = this;')) {
        if (functionStartPos !== -1) {
          // 找到函数定义的行
          const beforeFunctionText = contextBefore.substring(0, functionStartPos);
          const lastNewlinePos = beforeFunctionText.lastIndexOf('\n');
          const lastSpace = lastNewlinePos !== -1 ? beforeFunctionText.substring(lastNewlinePos).match(/^\s+/)[0] : '';

          // 计算函数定义在整个文本中的位置
          const functionLinePos = startPos - (contextBefore.length - lastNewlinePos);
          const selfStr = lastSpace + 'const _self = this;'

          // 在函数定义前插入 _self 定义
          result = result.substring(0, functionLinePos) +
            selfStr +
            result.substring(functionLinePos);

          startPos = startPos + selfStr.length;
          endPos = endPos + selfStr.length;
        }
      }
    }

    // 获取更多上下文，用于确定替换方式
    const beforeContext = result.substring(Math.max(0, startPos - 60), startPos);
    const afterContext = result.substring(endPos, Math.min(result.length, endPos + 60));

    // 检查引号类型
    let quoteType = '';
    if (beforeContext.endsWith("'")) {
      quoteType = "'";
    } else if (beforeContext.endsWith('"')) {
      quoteType = '"';
    }

    const selfStr = needImport ? 'i18n.t' : (needAddSelfDefinition ? '_self.$t' : 'this.$t');

    if (quoteType && beforeContext.endsWith(quoteType) && afterContext.startsWith(quoteType)) {
      result = result.substring(0, startPos - 1) +
        `${selfStr}(${i18nKey})` +
        result.substring(endPos + 1);
    } else if (/['"][^'"\s]+$/s.test(beforeContext) || /^[^'"\s]+['"]/s.test(afterContext)) {
      result = result.substring(0, startPos).replace(/(['|"])([^'"\s]*)$/s, '`$2') +
        `\${${selfStr}(${i18nKey})}` +
        result.substring(endPos).replace(/^([^'"\s$]*)(['"])/s, "$1`");
    } else if (/(`|\$\{)[^`]*$/s.test(beforeContext) || /^[^`\s]*`/s.test(afterContext)) {
      result = result.substring(0, startPos) +
        `\${${selfStr}(${i18nKey})}` +
        result.substring(endPos);
    } else {
      // 执行替换
      result = result.substring(0, startPos - 1) +
        `${selfStr}(${i18nKey})` +
        result.substring(endPos + 1);
    }
  }

  // 检查是否需要添加import语句
  if (allChineseArr.length > 0 && needImport && !result.includes('import i18n')) {
    result = `import i18n from '@/locale'\n${result}`;
  }

  return result
}

/**
 * 转义正则表达式中的特殊字符
 * @param {string} string - 需要转义的字符串
 * @returns {string} - 转义后的字符串
 */
function escapeRegExp (string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}

/**
 * 将Vue或JS文件中的中文替换为国际化key
 * @param {string} filePath - 文件路径
 * @param {Object} options - 配置选项
 * @param {string} options.moduleName - 模块名称
 * @param {boolean} options.excludeComparisonChinese - 是否排除比较语句中的中文
 * @param {Function} findKeyByChinese - 查找中文对应的翻译key的函数
 * @returns {Object} - 替换结果
 */
function replaceFileChineseWithI18n (filePath, options = {}, findKeyByChinese) {
  const fs = require('fs');
  const path = require('path');

  Object.keys(i18nConfig).forEach(key => {
    i18nConfig[key] = options[key] || i18nConfig[key]
  })

  // 合并配置
  const config = {
    ...i18nConfig,
    ...options
  };

  try {
    // 读取文件内容
    const fileContent = fs.readFileSync(filePath, 'utf8');
    const fileExt = path.extname(filePath).toLowerCase();
    const fileType = fileExt === '.vue' ? 'vue' : 'js';

    // 提取中文
    let chineseResult;
    if (fileType === 'vue') {
      chineseResult = findNonCommentChinese(fileContent);
    } else {
      chineseResult = findJsFileChinese(fileContent);
    }

    // 构建中文到国际化key的映射
    const chineseMap = {};
    const needToTranslate = {};
    const doNotTranslate = {};

    // 收集所有需要翻译的中文
    const allChinese = [];
    if (fileType === 'vue') {
      if (config.excludeComparisonChinese) {
        // 添加模板中的中文
        allChinese.push(...chineseResult.template.forTranslation.map(item => item.text));
        // 添加脚本中需要翻译的中文
        allChinese.push(...chineseResult.script.forTranslation.map(item => item.text));
      } else {
        // 如果不排除比较语句中的中文，导入全部
        allChinese.push(...chineseResult.template.all.map(item => item.text));
        allChinese.push(...chineseResult.script.all.map(item => item.text));
      }
    } else {
      // 添加JS文件中需要翻译的中文
      allChinese.push(...chineseResult.forTranslation.map(item => item.text));

      // 如果不排除比较语句中的中文，也加入
      if (!config.excludeComparisonChinese) {
        allChinese.push(...chineseResult.inComparison.map(item => item.text));
      }
    }

    // 去重
    const uniqueChinese = [...new Set(allChinese)];

    // 如果提供了findKeyByChinese函数，使用它查找已有的翻译
    if (findKeyByChinese && typeof findKeyByChinese === 'function') {
      const result = findKeyByChinese(uniqueChinese, false);

      // 处理已有翻译
      if (result.doNotTranslate) {
        Object.assign(doNotTranslate, result.doNotTranslate);
      }

      // 处理需要新增翻译的中文
      if (result.needToTranslate) {
        Object.assign(needToTranslate, result.needToTranslate);
      }
    } else {
      // 如果没有提供findKeyByChinese函数，所有中文都需要新增翻译
      uniqueChinese.forEach(chinese => {
        needToTranslate[chinese] = false;
      });
    }

    const commonNeedTranslate = {};


    let varText = '';
    // 为需要新增翻译的中文生成key
    for (let index = 0; index < Object.keys(needToTranslate).length; index++) {
      const chinese = Object.keys(needToTranslate)[index];
      varText = chinese;
      if (VAR_REGEX.test(chinese)) {
        const params = chinese.match(VAR_REGEX);
        params.forEach((param, index) => {
          varText = varText.replace(param, `{${index}}`);
        });
      }
      const key = generateI18nKey(filePath, index);
      commonNeedTranslate[varText] = key;
    }

    // 合并所有翻译
    Object.assign(chineseMap, doNotTranslate, commonNeedTranslate);

    // 替换中文
    const newContent = replaceChineseWithI18n(fileContent, chineseMap, fileType, chineseResult);

    // 如果内容有变化，写入文件
    if (newContent !== fileContent) {
      fs.writeFileSync(filePath, newContent, 'utf8');
      return {
        success: true,
        filePath,
        replaced: true,
        needToTranslate: commonNeedTranslate,
        doNotTranslate
      };
    }

    return {
      success: true,
      filePath,
      replaced: false,
      needToTranslate,
      doNotTranslate
    };
  } catch (error) {
    return {
      success: false,
      filePath,
      error: error.message
    };
  }
}

/**
 * 检查中文文本是否在比较语句中
 * @param {string} text - 中文文本
 * @param {string} surroundingText - 中文文本周围的上下文
 * @returns {boolean} - 是否在比较语句中
 */
function isInComparisonStatement (text, surroundingText) {
  // 转义正则表达式中的特殊字符
  const escapedText = escapeRegExp(text);

  return (
    // 比较操作符
    surroundingText.match(new RegExp(`===?\\s*['\"]?(${escapedText})['\"]?\\s*`)) ||
    surroundingText.match(new RegExp(`!==?\\s*['\"]?(${escapedText})['\"]?\\s*`)) ||
    // 字符串方法
    surroundingText.match(new RegExp(`\\.includes\\s*\\(['\"](${escapedText})['\"]`)) ||
    surroundingText.match(new RegExp(`\\.indexOf\\s*\\(['\"](${escapedText})['\"]`)) ||
    // 循环和条件语句中的比较
    surroundingText.match(new RegExp(`\\s+in\\s+['\"]?(${escapedText})['\"]?\\s*`)) ||
    surroundingText.match(new RegExp(`\\s+of\\s+['\"]?(${escapedText})['\"]?\\s*`)) ||
    // switch-case语句中的比较
    surroundingText.match(new RegExp(`case\\s+['\"]?(${escapedText})['\"]?\\s*:`)) ||
    // while循环中的比较
    surroundingText.match(new RegExp(`while\\s*\\([^)]*?===\\s*['\"]?(${escapedText})['\"]?`)) ||
    surroundingText.match(new RegExp(`while\\s*\\([^)]*?!==\\s*['\"]?(${escapedText})['\"]?`)) ||
    surroundingText.match(new RegExp(`while\\s*\\([^)]*?==\\s*['\"]?(${escapedText})['\"]?`)) ||
    surroundingText.match(new RegExp(`while\\s*\\([^)]*?!=\\s*['\"]?(${escapedText})['\"]?`))
  );
}

/**
 * 检查中文文本是否在注释内（JS、CSS或HTML注释）
 * @param {string} match - 中文文本
 * @param {string} surroundingText - 中文文本周围的上下文
 * @param {string} fileType - 文件类型，'vue'、'js'或'css'
 * @returns {boolean} - 是否在注释内
 */
function isInComment (match, surroundingText) {
  // 获取中文文本在上下文中的位置
  let textIndex = surroundingText.indexOf(match[0]);
  if (textIndex === -1) return false;
  if (Math.abs(textIndex - match.index) > 10) textIndex = match.index;

  // 提取中文文本之前的内容，用于检查是否在注释内
  const beforeText = surroundingText.substring(0, textIndex);

  // 检查是否在JavaScript单行注释内 (//)
  if (beforeText.lastIndexOf('//') > beforeText.lastIndexOf('\n')) {
    return true;
  }

  // 检查是否在JavaScript或CSS多行注释内 (/* */)
  let lastCommentStart = beforeText.lastIndexOf('/*');
  if (lastCommentStart !== -1) {
    let lastCommentEnd = beforeText.lastIndexOf('*/');
    // 如果找到注释开始，但没有找到注释结束，或者注释结束在注释开始之前，则在注释内
    if (lastCommentEnd === -1 || lastCommentEnd < lastCommentStart) {
      // 检查注释是否在中文文本之后结束
      const afterText = surroundingText.substring(textIndex);
      const nextCommentEnd = afterText.indexOf('*/');
      // 如果在中文文本之后找到注释结束，则确认在注释内
      if (nextCommentEnd !== -1) {
        return true;
      }
    }
  }

  // 如果是Vue文件，检查是否在HTML注释内 (<!-- -->)
  const lastHtmlCommentStart = beforeText.lastIndexOf('<!--');
  if (lastHtmlCommentStart !== -1) {
    const lastHtmlCommentEnd = beforeText.lastIndexOf('-->');
    // 如果找到注释开始，但没有找到注释结束，或者注释结束在注释开始之前，则在注释内
    if (lastHtmlCommentEnd === -1 || lastHtmlCommentEnd < lastHtmlCommentStart) {
      // 检查注释是否在中文文本之后结束
      const afterText = surroundingText.substring(textIndex);
      const nextHtmlCommentEnd = afterText.indexOf('-->');
      // 如果在中文文本之后找到注释结束，则确认在注释内
      if (nextHtmlCommentEnd !== -1) {
        return true;
      }
    }
  }

  return false;
}

// 导出函数
module.exports = {
  findNonCommentChinese,
  findJsFileChinese,
  i18nConfig,
  generateI18nKey,
  replaceChineseWithI18n,
  replaceFileChineseWithI18n,
  isInComment,
  isInComparisonStatement
};
